home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / knowhow4 / ljfonts.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-10  |  12.9 KB  |  560 lines

  1. #include <io.h>
  2. #include <fcntl.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <stdlib.h>
  6. #include "ljfonts.h"
  7.  
  8.  
  9. #define LJCHDSCFORMAT 4
  10. #define LJCHDSCCLASS  1
  11. #define LJCHDSCSIZE  14
  12. #define LJMINFDSC    26
  13.  
  14. #define MAXFL  64000  // maximum acceptable f
  15. #define MAXSCALE 16
  16.  
  17. #define SWAPB(w)  (((w & 0x00ff)<<8 ) + (w>>8))
  18.  
  19.  class far ljchardsc // class is used only through pointers
  20.  {
  21.   char Format; char Continuation;
  22.   char DescriptorSize; char Class;
  23.   char Orientation;/* 0 - portrait */ char Reserved;
  24.   unsigned _leftoffset;
  25.   unsigned _topoffset;
  26.   unsigned _charwidth;
  27.   unsigned _charheight;
  28.   unsigned _deltax;
  29.   char BitMap[4096];
  30.  
  31.   int LeftOffset()     {return SWAPB(_leftoffset );}
  32.   int TopOffset()      {return SWAPB(_topoffset  );}
  33.   int CharacterWidth() {return SWAPB(_charwidth  );}
  34.   int CharacterHeight(){return SWAPB( _charheight);}
  35.   int DeltaX()         {return SWAPB(_deltax     );}
  36.  
  37.  
  38.   int scaleDX(int xscale) // in dots !
  39.       { int deltax;
  40.         deltax=(DeltaX()>>2)/xscale;
  41.       if(deltax <= ( CharacterWidth() / xscale)) deltax++;
  42.       return deltax;}
  43.  
  44.   friend class ljfont;
  45. friend void drawscaledstr (const ljfont& font,uchar * s,int xscale,int yscale,int write_mode, int dir);
  46. friend void drawscaledchar(const ljfont& font,uchar c,int xscale,int yscale,int threshold,int write_mode, int dir);
  47. friend void drawstr(const ljfont& font,char * s,int transparent);
  48. friend void drawchar(const ljfont& font,char c,int transparent);
  49.  
  50. };
  51.  
  52.  
  53.  
  54. class ljfontdsc
  55.  {
  56.   unsigned _descriptorsize;
  57.   char Reserved2; char FontType;
  58.   unsigned _reserved4;
  59.   unsigned _baselinedist;
  60.   unsigned _cellwidth;
  61.   unsigned _cellheight;
  62.   char Orientation; /* 0 - portrait */ char  Spacing; /* 0 - fixed */
  63.   unsigned _symbolset;
  64.   unsigned _pitch;
  65.   unsigned  _height;
  66.   unsigned  _xheight;
  67.   char WidthType; char Style; /* 1 - italics */
  68.   signed char StrokeWeight;/*-7...7*/ char Typeface;
  69.   char Reserved26; char SerifStyle;
  70.   unsigned _reserved28;
  71.   signed char UnderlineDistance; char UnderlineHeight;
  72.   unsigned _textheight;
  73.   unsigned _textwidth;
  74.   unsigned _reserved36;
  75.   unsigned _reserved38;
  76.   char PitchExtended; char HeightExtended;
  77.   unsigned _reserved42;
  78.   unsigned _reserved44;
  79.   unsigned _reserved46;
  80.   char FontName[16]; // Not 0 - terminated !
  81.  
  82.   int DescriptorSize()  {return SWAPB( _descriptorsize );}
  83.   int BaselineDistance(){return SWAPB( _baselinedist   );}
  84.   int CellWidth()       {return SWAPB(_cellwidth       );}
  85.   int CellHeight()      {return SWAPB( _cellheight     );}
  86.   int Pitch()           {return SWAPB(_pitch           );}
  87.   int Height()        {return SWAPB( _height         );}
  88.   int xHeight()        {return SWAPB(_xheight         );}
  89.   int TextHeight()    {return SWAPB( _textheight     );}
  90.   int TextWidth()     {return SWAPB( _textwidth      );}
  91.  
  92.        friend class ljfont;
  93. };
  94.  
  95.  
  96.  
  97. int gethpparm(const char * s,char Expected_delimiter, char *& result)
  98.  // s points to start of digits
  99.  // get ascii parameter of PCL command
  100.  // returns -1 on error
  101.  // result points after the delimeter
  102.   { char  a[10]; int i,n;
  103.  
  104.      for (i=0;i<8 && s[i]!=Expected_delimiter;i++)a[i]=s[i];
  105.      if( s[i]!=Expected_delimiter) return -1;
  106.      a[i]='\0';
  107.      if (! isdigit(a[0])) return -1;
  108.      n = atoi(a);
  109.      result=(char*)s+i+1;
  110.      return n;
  111.   }
  112.  
  113.  int fits(const char * s,const char * pattern)
  114.   // returns  1 - ok
  115.   //          0 - does not fit
  116.   {
  117.       while (*pattern) if(*pattern++ != *s ++) return 0;
  118.       return 1;
  119.  }
  120.  
  121.  
  122. inline ljchardsc far * ljfont::operator[](uchar n) const
  123.    {
  124.     void _seg * datas = (void _seg*) (void far*)data;
  125.     return letters[n]? datas +letters[n] : 0;
  126.   }
  127.  
  128.  
  129.  ljfont::ljfont(const char * name) :ok(0)
  130.   { int i,f,n,c; long l; char * buf; char * s,* s_end;
  131.     for (i=0;i<256;i++)
  132.      {
  133.       letters[i]=0;
  134.       }
  135.     f=_open(name,O_RDONLY);
  136.     if (f<0) return;
  137.     l=filelength(f);
  138.     if(l<0) return;
  139.     if (l>MAXFL) return;
  140.     data=buf=new char[l];
  141.      s_end=buf+l;
  142.     if (! buf) return;
  143.     n=_read(f,buf,l);
  144.     if((n==-1) || (unsigned(n)<l)) return;
  145.     _close(f);
  146.  
  147.  
  148.     if (! fits(buf,"\x1b)s") ) return; // font header
  149.     if ( (i=gethpparm(buf+3,'W',s)) <= 0 ) return;
  150.     descriptor=(ljfontdsc *) s;
  151.     if (descriptor->DescriptorSize() <LJMINFDSC) return;
  152.     if (descriptor->Orientation!=0) return;
  153.       s+=i;      //skip_header
  154.  
  155.  
  156.   while(s<s_end)
  157.    {
  158.     if (! fits(s,"\x1b*c")) break; //char #
  159.     c=gethpparm(s+3,'E',s); if(c<0 || c >255) break;
  160.     if (! fits(s,"\x1b(s"))break; //char data
  161.     if ( (i=gethpparm(s+3,'W',s)) <= 0 ) break;
  162.     letters[c]= (ljchardsc near *) s;
  163.     s+=i;
  164.   }
  165.  
  166.     ljchardsc far * dsc;
  167.  
  168.   //now check char descriptors
  169.     for (i=0;i<256;i++)
  170.     {
  171.      if (letters[i]==0) continue;
  172.       dsc=  operator[](i);
  173.       if( dsc->Format !=   LJCHDSCFORMAT) return;
  174.       if( dsc->Class!= LJCHDSCCLASS) return;
  175.       if( dsc->DescriptorSize!=LJCHDSCSIZE)return;
  176.       if( dsc->Orientation !=0) return; // landscape not supported
  177.                     // for now
  178.  
  179.  
  180.     }
  181.  
  182.     ok=1;
  183.  }
  184.  
  185.  
  186.  
  187.    ljfont:: ~ljfont()
  188.    {
  189.     delete ((char*) data);
  190. //    delete data;
  191.  }
  192.  
  193.  
  194.  
  195. void putpixel(int x,int y,int color,int write_mode) // overloaded putpixel
  196. { int screen;
  197.   if (write_mode & 3) screen=getpixel(x,y);
  198.   switch(write_mode)
  199.   {
  200.     case COPY_PUT:putpixel(x,y,color);  break;
  201.     case XOR_PUT: putpixel(x,y, color ^ screen);  break;
  202.     case OR_PUT:  putpixel(x,y, color | screen);  break;
  203.     case AND_PUT: putpixel(x,y, color & screen);  break;
  204.     case NOT_PUT: putpixel(x,y, ~color);  break;
  205.  
  206.   }
  207. }
  208.  
  209.  
  210.  
  211. /*
  212.  
  213.   öπ¡¬µ¿¿ ñ½∩ αÑ὿ºáµ¿¿ ß¿ßΓÑ¼δ ¬««αñ¿¡áΓ, »«óÑα¡πΓ«⌐ ¡á 90°
  214.  
  215. */
  216. inline int getx(int dir)
  217. {
  218.  if(dir) return gety();
  219.  return getx();
  220. }
  221.  
  222. inline int gety(int dir)
  223. {
  224.  if(dir) return getmaxx() - getx();
  225.  return gety();
  226. }
  227.  
  228. inline int getmaxx(int dir)
  229. {
  230. if(dir) return getmaxy();
  231. return getmaxx();
  232. }
  233. inline int getmaxy(int dir)
  234. {
  235. if(dir) return getmaxx();
  236. return getmaxy();
  237. }
  238.  
  239. inline void putpixel(int x, int y,int color, int write_mode, int dir)
  240. {
  241. if(dir) putpixel(y, getmaxx() - x, color, write_mode);
  242. else putpixel(x, y, color, write_mode);
  243. }
  244.  
  245. inline void moveto(loc xy, int dir)
  246.     {
  247.     if(dir) moveto(xy.Y, getmaxx() - xy.X);
  248.     else moveto(xy);
  249.     }
  250.  
  251. inline void moverel(int x, int y, int dir)
  252. {
  253.  if (dir) moverel(y, x);
  254.  else moverel(x,y);
  255. }
  256. /*
  257. inline int getx(int dir)
  258. {
  259.  if(dir) return getmaxy()-gety();
  260.  return getx();
  261. }
  262.  
  263. inline int gety(int dir)
  264. {
  265.  if(dir) return getx();
  266.  return gety();
  267. }
  268.  
  269. inline int getmaxx(int dir)
  270. {
  271. if(dir) return getmaxy();
  272. return getmaxx();
  273. }
  274. inline int getmaxy(int dir)
  275. {
  276. if(dir) return getmaxx();
  277. return getmaxy();
  278. }
  279.  
  280. inline void putpixel(int x, int y,int color, int write_mode, int dir)
  281. {
  282. if(dir) putpixel(getmaxy()-y,x, color, write_mode);
  283. else putpixel(x, y, color, write_mode);
  284. }
  285.  
  286. inline void moverel(int x, int y, int dir)
  287. {
  288.  if (dir) moverel(y,-x);
  289.  else moverel(x,y);
  290. }
  291. */
  292.  
  293.  void drawchar(const ljfont& font,char c,int transparent)
  294.    {  int x,y,x0,y0,x1,y1; ljchardsc far * symbol;
  295.       int bytesperrow,nrows,ncols;  int color,bkcolor;
  296.       int i,bi,by;char B;
  297.  
  298.        symbol=font [c];
  299.        if (symbol==0) return;
  300.        color=getcolor();
  301.        if(! transparent )
  302.     { fillsettingstype fs;
  303.       getfillsettings (&fs);
  304.       bkcolor=fs.color;
  305.     }
  306.        x0=getx(); y0=gety();
  307.        y0-=symbol->TopOffset();
  308.        x0+=symbol->LeftOffset();
  309.   //      getviewsettings(&vp); - not necessary
  310.        ncols=symbol->CharacterWidth();
  311.        bytesperrow=(ncols+7) >>3;
  312.        nrows=symbol->CharacterHeight();
  313.     y1=y0+nrows-1;
  314.     x1=x0+ncols-1;
  315.     if(x0<0 || y0 <0) return;
  316.     if(x0+ncols>getmaxx() || y0+nrows >getmaxy())return;
  317.  
  318.     for (y=y0,by=0;y<=y1;y++)
  319.      {
  320.  
  321.       for (x=x0,i=1;i<=bytesperrow;i++)
  322.         {
  323.            B=symbol->BitMap[by];
  324.            for(bi=0;bi<=7 && x<=x1;bi++,x++)
  325.           {
  326.               asm shl B,1
  327.               asm jc black
  328.               asm jmp white
  329.              black:
  330.                putpixel(x,y,color);
  331.                continue;
  332.              white:
  333.              if(! transparent)
  334.                putpixel(x,y,bkcolor);
  335.  
  336.           }
  337.         by++;
  338.         }
  339.      }
  340.  
  341.     moverel(symbol->DeltaX()>>2,  0);
  342.  
  343.    }
  344.  
  345.  
  346.  
  347.  
  348.    void drawstr(const ljfont& font,char * s,int transparent)
  349.      {
  350.        while(*s) drawchar(font,*s++,transparent);
  351.  
  352.      }
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362. #ifndef __MIN_AND_MAX_H
  363.  
  364.  inline int min(int x,int y)
  365.   {
  366.    return x<y ? x :y;
  367.  
  368. }
  369. #endif
  370. /*
  371.  
  372.  
  373.  
  374.   öπ¡¬µ¿∩ α¿ßπÑΓ ß¿¼ó«½ ½áºÑα¡«ú« Φα¿ΣΓá , π¼Ñ¡∞ΦÑ¡δ⌐ ó µÑ½«Ñ τ¿ß½« αáº
  375. »« ú«α¿º«¡Γ὿/óÑαΓ¿¬á½¿.
  376.  
  377.  èáªñá∩ Γ«τ¬á π¼Ñ¡∞ΦÑ¡¡«ú« ß¿¼ó«½á ß««ΓóÑΓßΓóπÑΓ xscale * yscale Γ«τ¬á¼
  378. ¿ßσ«ñ¡«ú« Φα¿ΣΓá. Åáαá¼ÑΓα threshold «»αÑñѽ∩ÑΓ ß¬«½∞¬« "τÑα¡δσ" Γ«τѬ
  379. ñ«½ª¡« íδΓ∞ ó ¿ßσ«ñ¡«⌐ ¬½ÑΓ¬Ñ, τΓ«íδ ÑÑ ¿º«íαáªÑ¡¿Ñ ßΓὫ "τÑα¡δ¼".
  380.  
  381.  Ä»Γ¿¼á½∞¡«Ñ º¡áτÑ¡¿Ñ φΓ«ú« »áαá¼ÑΓαá, ¬á¬ »αá󿽫 = xscale * yscale /2
  382.  
  383.  
  384. Åα¿¼Ñα
  385.  
  386.       ┌── xscale   yscale ─────────────────┐
  387.       │                                    │
  388.       │                                    │
  389.     │<┴─>│.    .    .     .     .  nd .    │
  390.     .............................. ns      │
  391.    .╔╤╤╤╤╦╤╤╕╒╤╦╤╤╤╤╦╕╒╤╤╤╦╤╤╤╕╒╦╤╤╕  ──   │
  392.    .╟┼┼┼┼╫┼┼┤├┼╫┼┼┼┼╫┤├┼┼┼╫┼┼┼┤├╫┼┼┤      │
  393.    .╟┼┼┼┼╫┼┼┤├┼╫┼┼┼┼╫┤├┼┼┼╫┼┼┼┤├╫┼┼┤   ├───┘
  394.    .╟┼┼┼┼╫┼┼┤├┼╫┼┼┼┼╫┤├┼┼┼╫┼┼┼┤├╫┼┼┤   
  395. .  .╠╪╪╪╪╬╪╪╡╞╪╬╪╪╪╪╬╡╞╪╪╪╬╪╪╪╡╞╬╪╪╡  ──
  396.    .╟┼┼┼┼╫┼┼┤├┼╫┼┼┼┼╫┤├┼┼┼╫┼┼┼┤├╫┼┼┤
  397.    .╟┼┼┼┼╫┼┼┤├┼╫┼┼┼┼╫┤├┼┼┼╫┼┼┼┤├╫┼┼┤
  398.    .╟┼┼┼┼╫┼┼┤├┼╫┼┼┼┼╫┤├┼┼┼╫┼┼┼┤├╫┼┼┤
  399. .  .╠╪╪╪╪╬╪╪╡╞╪╬╪╪╪╪╬╡╞╪╪╪╬╪╪╪╡╞╬╪╪╡
  400.   ms╙┴┴┴┴╨┴┴┘└┴╨┴┴┴┴╨┘└┴┴┴╨┴┴┴┘└╨┴┴┘
  401.  
  402.  
  403. .
  404. md
  405.  
  406.  
  407.   Vertical scale 4:1, horizontal 5:1, original image size 28 x 9,
  408.   scaled image size would be 6 x 3
  409.  
  410.  
  411.  
  412.  
  413.  
  414. */
  415.  
  416.  void drawscaledchar(const ljfont& font,uchar c,int xscale,int yscale,int threshold,int write_mode, int dir)
  417.    {  int x,y,x0,y0; ljchardsc far * symbol;
  418.       int bw,bwd,ms,ns,md;  int color;
  419.       int j,bi,by,byj;char B[MAXSCALE]; int DeltaX;int  is,jd,doti;
  420.       // is - ßτÑΓτ¿¬ í¿Γ«ó ó ¿ßσ«ñ¡«¼ í¿Γ«ó«¼ «íαáºÑ (ú«α¿º.)
  421.       // bi - ñѬαÑ¼Ñ¡Γ¡δ⌐ ßτÑΓτ¿¬ í¿Γ«ó ó íá⌐ΓÑ
  422.       // doti  - ñѬαÑ¼Ñ¡Γ¡δ⌐ ßτÑΓτ¿¬ í¿Γ«ó ó ú«α¿º«¡Γá½∞¡«⌐ »α«Ñ¬µ¿¿ Γ«τ¬¿
  423.       // jd - óÑαΓ¿¬á½∞¡δ⌐ ßτÑΓτ¿¬ ßΓ᫬, óδñáóáѼδσ ¡á φ¬αá¡
  424.  
  425.       int bitmapsize; int dotheight;  int sum;
  426.               /*last dots are not necessary xscale x yscale*/
  427.        _SI=0;
  428.        symbol=font [c];
  429.        if (symbol==0) return;
  430.        if (xscale <=0 || yscale <= 0 || yscale >MAXSCALE) return;
  431.        color=getcolor();
  432.        x0=getx(dir); y0=gety(dir);
  433.        y0-=symbol->TopOffset()/yscale;
  434.        x0+=symbol->LeftOffset()/xscale;
  435.        ns=symbol->CharacterWidth(); // number of cols
  436.        bw=(ns+7) >>3;               // bytes per row
  437.        bwd=bw*(yscale-1)+1;
  438.                       // delta for the next dest row
  439.        ms=symbol->CharacterHeight();// # of rows
  440.        bitmapsize= bw*ms;
  441.  
  442. //       nd= (ns+xscale-1) /xscale;   // # of dest cols
  443.        md= (ms+yscale-1) /yscale;   // # of dest rows
  444. //    y1=y0+md-1;
  445. //    x1=x0+nd-1;
  446. //    if(x0<0 || y0 <0) return;
  447. //    if(x1>getmaxx(dir) || y1>getmaxy(dir))return;
  448.     DeltaX= symbol->scaleDX(xscale);         //
  449.  
  450.  
  451.     x=x0;y=y0;
  452.     by=0; //current  byte in bitmap array
  453.  
  454.  
  455.  
  456.  
  457. for ( jd=0;jd<md;jd++,y++)
  458. {
  459.     is=0;
  460.     sum=0; doti=min(xscale,ns-is);
  461.  
  462. next_byte:
  463.     for (byj=by,j=0;j<yscale && byj<bitmapsize;byj+=bw,j++)
  464.          B[j]=symbol->BitMap[byj]; dotheight=j; bi=8;
  465.  
  466.  
  467.        // load B[]
  468.  
  469.  
  470.       /* count the sum of bits in one column */
  471. next_col:
  472.          asm {
  473.            mov cx,dotheight
  474.            jcxz counted
  475.            mov ax,sum
  476.            lea si,B[0]
  477.          }
  478. do_count:
  479.         asm{
  480.  
  481.            shl byte ptr ss:[si],1
  482.            adc ax,0
  483.            inc si
  484.            loop  do_count
  485.            mov sum,ax
  486.          }
  487.  
  488. counted:   is++;bi--;doti--;
  489.  
  490.        if(!doti) {  // dot is exhausted
  491.  
  492.            if (sum >= threshold)
  493.           putpixel(x,y,color,write_mode,dir);
  494.            sum=0; doti=min(xscale,ns-is);
  495.            x++;
  496.  
  497.  
  498.            }
  499.  
  500.  
  501.        if ( is==ns )  { by+=bwd; x=x0; continue;}
  502.        if (!bi) {by++; goto next_byte;} // byte is exhausted
  503.        else  goto next_col;
  504. }
  505.  
  506.  
  507.  
  508.       moverel(DeltaX,0,dir);
  509. }
  510.  
  511.  
  512.  
  513. rect ljfont::textsize( const char * s) const
  514.   { int h=0,d=0,w=0; ljchardsc far * chard;
  515.     int up,down;
  516.     while(*s)
  517.     {
  518.      chard =(*this) [*s++];
  519.      if (chard)
  520.      {   up= chard-> TopOffset();
  521.          down= chard->CharacterHeight()-up-1;
  522.           h=max(h,up);
  523.           d=max(d,down);
  524.           w+=chard->DeltaX() >> 2;
  525.       }
  526.     }
  527.    return rect(0,-h, w-1,d);
  528.   }
  529.  
  530.  
  531. rect ljfont::scaledtextsize(const char * s,int xscale,int yscale) const
  532.   {
  533.      int h=0,d=0,w=0; ljchardsc far * chard;
  534.      int up,down;
  535.      while(*s)
  536.        {
  537.         chard =(*this) [*s++];
  538.         if (chard)
  539.         {   up= chard-> TopOffset() /yscale;
  540.             down= (chard->CharacterHeight()+yscale-1)/yscale - up-1;
  541.              h=max(h,up);
  542.              d=max(d,down);
  543.              w+=chard->scaleDX(xscale);
  544.          }
  545.        }
  546.  
  547.     return rect(0,-h, w-1,d);
  548.   }
  549.  
  550.  void drawscaledstr (const ljfont& font,uchar * s,int xscale,int yscale,int write_mode, int dir)
  551.  
  552.   {  int threshold= xscale* yscale /2;
  553.      if(threshold<1) threshold=1;
  554.  
  555.      while(*s)
  556.       drawscaledchar(font,*s++,xscale,yscale,threshold,write_mode,dir);
  557.  
  558.  }
  559.  
  560.